
// 自定义滚动条效果
function mScroll(init){
	if(!init.el){
		return;
	}
	var wrap = init.el;
	var inner = init.el.children[0];
	var iX = 0; // 鼠标初始X轴位置
	var iY = 0; // 鼠标初始Y轴位置
	var startEl = 0; // 元素初始位置（transform初始值）
	var lastY = 0; // 上一次的距离
	var lastDis = 0; // 最后一次的距离
	var lastTime = 0; // 上一次时间
	var lastTimeDis = 0; // 时间差
	var maxTranslateY = wrap.clientHeight - inner.offsetHeight; // 最大可滚动距离
	var range = 40; // 和提示语的高度保持一致
	var timer1 = '';
	var timer2 = '';
	var timer3 = '';

	inner.style.minHeight = "100%";

	if(init.dropUp){
		var dropup = document.querySelector(".dropload-up");
		var dropupdate = document.querySelector(".dropload-update");
		var dropupload = document.querySelector(".upLoading");	
	}

	if(init.dropDown){
		var dropdown = document.querySelector(".dropload-down");
		var dropdownLoad = document.querySelector(".downLoading");
		var dropdownNoData = document.querySelector(".dropload-noData");
	}

	if(init.showBar){
		var scrollBar = document.createElement("div");	
		scrollBar.className = "scrollBar";
		scrollBar.style.cssText = "width:4px;height:50px;background:rgba(0,0,0,.5);position:absolute;right:0;top:0;border-radius:3px;opacity:0;transition:.3s opacity;";
		wrap.appendChild(scrollBar);

		var maxScrollTransY = scrollBar.offsetHeight - wrap.clientHeight; // 滚动条可移动的最大距离 （负值）
		var scale = maxScrollTransY / maxTranslateY;
	}
	
	// 添加硬件加速
	css(inner,"translateZ",0.01);

	inner.addEventListener('touchstart', function(e) {
		maxTranslateY = wrap.clientHeight - inner.offsetHeight; // 再写一遍是避免 元素高度小于滚动区域时，inner最小高度为100%
		if(init.showBar){
			scale = maxScrollTransY / maxTranslateY;
			if(maxTranslateY >= 0) {
				scrollBar.style.display = "none";
			} else {
				scrollBar.style.display = "block";
			}
		}
		clearInterval(inner.timer);
		iX = e.changedTouches[0].pageX;
		iY = e.changedTouches[0].pageY;
		startEl = css(inner,"translateY");
		lastY = startEl;
		lastTime = new Date().getTime();
		lastTimeDis = lastDis = 0;
		(!init.showBar)||(scrollBar.style.opacity = 1);
		init.start && init.start.call(wrap, e);
	});

	inner.addEventListener('touchmove', function(e) {
		
		var nowTime = new Date().getTime();
		var nowPointX = e.changedTouches[0].pageX;
		var nowPointY = e.changedTouches[0].pageY;
		var disX = nowPointX - iX;
		var disY = nowPointY - iY;

		if(Math.abs(disY) > Math.abs(disX) ){ // 为true时就是Y轴滚动 （为了不影响滚动条范围内的banner轮播效果）

			if( disY > 0 ){ // 列表头部 下拉刷新出现
				if( init.dropUp ){
					dropupload.style.opacity  = 0;
					dropupdate.style.opacity = 1;
				}
			}

			var translateY = startEl + disY;

			if( translateY > range ){ // 控制顶部拖拽的幅度
				translateY = range;
			}else if(translateY < maxTranslateY - range){ // 控制最底部拖拽的幅度
				translateY = maxTranslateY - range;
			}

			css(inner,"translateY",translateY);
			(!init.showBar)||css(scrollBar,"translateY", Math.round(-translateY * scale));
			lastDis = translateY - lastY;
			lastY = translateY;
			lastTimeDis = nowTime - lastTime;
			lastTime = nowTime;
			
			var disTrans = Math.abs(translateY) - Math.abs(maxTranslateY);
			if( Math.abs(disTrans) < 500 && init.dropDown ){ // 列表底部 上拉加载出现 （给个500的浮动）
				dropdownNoData.style.opacity = 0;
				dropdownLoad.style.opacity = 1;
			}
		}

		init.move && init.move.call(wrap,e);
	});

	inner.addEventListener('touchend', function(e) {
		var type = "easeOut";
		var speed = Math.round(lastDis / lastTimeDis*10);
		speed = lastTimeDis <= 0?0 :speed;
		var target = Math.round(speed*30 + css(inner,"translateY")); // 滚动到最接近底部的时候

		if(target > 0){ // 已经滑到最顶部了
			if( init.dropUp ){  // 定义了dropUp
				dropupdate.style.opacity = 0;
				dropupload.style.opacity = 1;

				(!init.isRefresh) || updateNewPage(); // isRefresh为true就执行上拉刷新，刷新新页面

				clearTimeout(timer1);
				timer1 = setTimeout(function(){ // 1s后回弹回头部
					dropupload.style.opacity  = 0;
					target = 0;
					type = "backOut";

					MTween({
						el:inner,
						target: {translateY:target},
						time: 1000,
						type: type,
						callBack: function(){
							(!init.showBar) || (scrollBar.style.opacity = 0);
						},
						callIn: function(){
							var translateY = css(inner,"translateY");
							(!init.showBar) || css(scrollBar,"translateY", Math.round(-translateY * scale));
						}
					});
				},400)
				return;
			}else{
				target = 0;
				type = "backOut";
			}
		} else if( target < maxTranslateY ){ // 已经滑到最底部了
			if( init.dropDown ){ // 定义了dropDown
				target = maxTranslateY;
				type = "backOut";
				dropdownLoad.style.opacity = 0;
				dropdownNoData.style.opacity = 1;
				clearTimeout(timer2);
				timer2 = setTimeout(function(){
					dropdownLoad.style.opacity = 0;
					dropdownNoData.style.opacity = 0;
					MTween({
						el:inner,
						target:{
							translateY:target
						},
						time:1000,
						type:"easeBoth",
						callBack: function(){
							(!init.showBar) || (scrollBar.style.opacity = 0);
						},
						callIn: function(){
							var translateY = css(inner,"translateY");
							(!init.showBar) || css(scrollBar,"translateY", Math.round(-translateY * scale));
						}
					});
				},400);
				return;	
			}else{
				target = maxTranslateY;
				type = "backOut";	
			}
		}

		// 非最顶部和最底部的元素滚动和滚动条离上距离
		MTween({
			el:inner,
			target: {translateY:target},
			time: Math.round(Math.abs(target - css(inner,"translateY"))*1.8),
			type: type,
			callBack: function(){
				(!init.showBar) || (scrollBar.style.opacity = 0);
				init.move && init.move.call(wrap,e);
			},
			callIn: function(){
				var translateY = css(inner,"translateY");
				(!init.showBar) || css(scrollBar,"translateY", Math.round(-translateY * scale));
				init.over && init.over.call(wrap,e);
			}
		});
		
		init.end && init.end.call(wrap, e);
	});
}


// 妙味提供的m.Tween.js里面的代码
var Tween = {
	linear: function (t, b, c, d){
		return c*t/d + b;
	},
	easeIn: function(t, b, c, d){
		return c*(t/=d)*t + b;
	},
	easeOut: function(t, b, c, d){
		return -c *(t/=d)*(t-2) + b;
	},
	easeBoth: function(t, b, c, d){
		if ((t/=d/2) < 1) {
			return c/2*t*t + b;
		}
		return -c/2 * ((--t)*(t-2) - 1) + b;
	},
	easeInStrong: function(t, b, c, d){
		return c*(t/=d)*t*t*t + b;
	},
	easeOutStrong: function(t, b, c, d){
		return -c * ((t=t/d-1)*t*t*t - 1) + b;
	},
	easeBothStrong: function(t, b, c, d){
		if ((t/=d/2) < 1) {
			return c/2*t*t*t*t + b;
		}
		return -c/2 * ((t-=2)*t*t*t - 2) + b;
	},
	elasticIn: function(t, b, c, d, a, p){
		if (t === 0) { 
			return b; 
		}
		if ( (t /= d) == 1 ) {
			return b+c; 
		}
		if (!p) {
			p=d*0.3; 
		}
		if (!a || a < Math.abs(c)) {
			a = c; 
			var s = p/4;
		} else {
			var s = p/(2*Math.PI) * Math.asin (c/a);
		}
		return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
	},
	elasticOut: function(t, b, c, d, a, p){
		if (t === 0) {
			return b;
		}
		if ( (t /= d) == 1 ) {
			return b+c;
		}
		if (!p) {
			p=d*0.3;
		}
		if (!a || a < Math.abs(c)) {
			a = c;
			var s = p / 4;
		} else {
			var s = p/(2*Math.PI) * Math.asin (c/a);
		}
		return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
	},    
	elasticBoth: function(t, b, c, d, a, p){
		if (t === 0) {
			return b;
		}
		if ( (t /= d/2) == 2 ) {
			return b+c;
		}
		if (!p) {
			p = d*(0.3*1.5);
		}
		if ( !a || a < Math.abs(c) ) {
			a = c; 
			var s = p/4;
		}
		else {
			var s = p/(2*Math.PI) * Math.asin (c/a);
		}
		if (t < 1) {
			return - 0.5*(a*Math.pow(2,10*(t-=1)) * 
					Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
		}
		return a*Math.pow(2,-10*(t-=1)) * 
				Math.sin( (t*d-s)*(2*Math.PI)/p )*0.5 + c + b;
	},
	backIn: function(t, b, c, d, s){
		if (typeof s == 'undefined') {
		   s = 1.70158;
		}
		return c*(t/=d)*t*((s+1)*t - s) + b;
	},
	backOut: function(t, b, c, d, s){
		if (typeof s == 'undefined') {
			s = 2.70158;  //回缩的距离
		}
		return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
	}, 
	backBoth: function(t, b, c, d, s){
		if (typeof s == 'undefined') {
			s = 1.70158; 
		}
		if ((t /= d/2 ) < 1) {
			return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
		}
		return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
	},
	bounceIn: function(t, b, c, d){
		return c - Tween['bounceOut'](d-t, 0, c, d) + b;
	},       
	bounceOut: function(t, b, c, d){
		if ((t/=d) < (1/2.75)) {
			return c*(7.5625*t*t) + b;
		} else if (t < (2/2.75)) {
			return c*(7.5625*(t-=(1.5/2.75))*t + 0.75) + b;
		} else if (t < (2.5/2.75)) {
			return c*(7.5625*(t-=(2.25/2.75))*t + 0.9375) + b;
		}
		return c*(7.5625*(t-=(2.625/2.75))*t + 0.984375) + b;
	},      
	bounceBoth: function(t, b, c, d){
		if (t < d/2) {
			return Tween['bounceIn'](t*2, 0, c, d) * 0.5 + b;
		}
		return Tween['bounceOut'](t*2-d, 0, c, d) * 0.5 + c*0.5 + b;
	}
};
function css(element, attr , val){
	if(attr == "scale"||attr == "scaleX"
	||attr == "scaleY"||attr == "scaleZ"
	||attr == "rotateX"||attr == "rotateY"
	||attr == "rotateZ"||attr == "rotate"
	||attr == "skewX"||attr == "skewY"
	||attr == "translateX"||attr == "translateY"
	||attr == "translateZ") {
		return cssTransform(element, attr, val);
	}
	if(arguments.length == 2){
		var val = getComputedStyle(element)[attr];
		if(attr=='opacity'){
			val = Math.round(val*100);
		}
		return parseFloat(val);
	} 
	if(attr == "opacity") {
		element.style.opacity= val/100;
	} else {
		element.style[attr]= val + "px";	
	}
}
function cssTransform(element, attr, val){
	if(!element.transform){
		element.transform = {};
	}	
	if(typeof val === "undefined"){ 
		if(typeof element.transform[attr] === "undefined"){
			switch(attr){
				case "scale":
				case "scaleX":
				case "scaleY":
				case "scaleZ":
					element.transform[attr] = 100;
					break;
				default:
					element.transform[attr] = 0;	
			}
		} 
		return element.transform[attr];
	} else {
		element.transform[attr] = val;
		var transformVal  = "";
		for(var s in element.transform){
			switch(s){
				case "scale":
				case "scaleX":
				case "scaleY":
				case "scaleZ":
					transformVal += " " + s + "("+(element.transform[s]/100)+")";
					break;
				case "rotate":
				case "rotateX":
				case "rotateY":
				case "rotateZ":
				case "skewX":
				case "skewY":
					transformVal += " " + s + "("+element.transform[s]+"deg)";
					break;
				default:
					transformVal += " " + s + "("+element.transform[s]+"px)";				
			}
		}
		element.style.WebkitTransform = element.style.transform = transformVal;
	}
}
function MTween(init){
	var t = 0;
	var b = {};
	var c = {};
	var d = init.time / 20;
	for(var s in init.target){ 
		b[s] = css(init.el, s); 
		c[s] = init.target[s] - b[s];
	}
	clearInterval(init.el.timer); 
	init.el.timer = setInterval(
		function(){
			t++;
			if(t>d){
				clearInterval(init.el.timer);
				init.callBack&&init.callBack.call(init.el);
			} else {
				init.callIn&&init.callIn.call(init.el);
				for(var s in b){
					var val = Number((Tween[init.type](t,b[s],c[s],d)).toFixed(2));
					css(init.el, s, val);
				}
			}
		},
		20
	);
}
